package gitee.derumin.teleport_compass.mixin;

import gitee.derumin.lib_for_derumin.api.features.ChunkDataTools;
import gitee.derumin.teleport_compass.Teleport_compass;
import gitee.derumin.teleport_compass.waypoints.Waypoints;
import net.minecraft.block.BlockState;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.Text;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

@Mixin(BlockItem.class)
public abstract class BlockItemMixin extends Item {

    @Shadow protected abstract boolean place(ItemPlacementContext context, BlockState state);

    public BlockItemMixin(Settings settings) {
        super(settings);
    }

    @Redirect(method = "place(Lnet/minecraft/item/ItemPlacementContext;)Lnet/minecraft/util/ActionResult;", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/BlockItem;place(Lnet/minecraft/item/ItemPlacementContext;Lnet/minecraft/block/BlockState;)Z"))
    private boolean tryPlaceAndSetWaypoint(BlockItem instance, ItemPlacementContext context, BlockState state){
        ItemStack stack = context.getStack();
        if (Teleport_compass.isWaypointLodestone(stack)){
            World world = context.getWorld();
            BlockPos pos = context.getBlockPos();
            if (world.getBlockState(pos.up()).isAir() && world.getBlockState(pos.up(2)).isAir()){
                boolean bl = this.place(context, state);
                if (bl && context.getWorld() instanceof ServerWorld serverWorld){
                    Waypoints waypoints = (Waypoints) ChunkDataTools.getExtraData(serverWorld, pos, Waypoints.ID);
                    if (waypoints != null){
                        Text name = stack.get(DataComponentTypes.CUSTOM_NAME);
                        if (name == null){
                            name = Teleport_compass.getDefaultWaypointName(pos);
                        }
                        waypoints.trySetWaypoint(serverWorld, pos, name);
                    }
                }
                return bl;
            }else {
                if (context.getPlayer() instanceof ServerPlayerEntity serverPlayer){
                    serverPlayer.currentScreenHandler.syncState();
                }
                return false;
            }
        }else {
            return this.place(context, state);
        }
    }
}
